/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

 /*
  * TEST
  * 
  * a=1,b=1,g=1,l=1,ha=9,hb=9,hg=9,hl=9 ==> hk=9,g=1,c=1,hm=9,b=1,a=1,hc=9,hg=9,l=1,hb=9,hl=9,ha=9,k=1,m=1
  */

def records = new XmlParser().parse(new File("src/reglas.xml"));
/*
 records.rule.each{
 println "\n==== Rule ${it.@id} ===="
 println "if"
 it.if.attr.each{
 println "   ${it.@name}  =  ${it.text()}"
 }
 println "then"
 it.then.attr.each{
 println "   ${it.@name}  =  ${it.text()}"
 }
 }
 */
def CONDICIONES = "Ingrese condiciones (ej c1=v1,c2=v2): "
def OBJETIVO = "Ingrese objetivo (ej cO=vO): "

BufferedReader br = new BufferedReader(new InputStreamReader(System.in))

def input = { message, map->
	print "\n\n${message}"
	def ingreso = br.readLine()	
	ingreso.split(",").each{
		def r = it.split("=")
		map.put(r[0], r[1])
	}
}

println "\n\n==== Motor de Inferencia ===="


print "\n${OBJETIVO}"
def obj = br.readLine()

def mapEntrada = new HashMap<String, String>()
input(CONDICIONES, mapEntrada)

def checkRule = { it, lista, wk, forward ->
	print "\n     Regla ${it.@id}  ==>"
	def valeRegla = true
	def rule = new Rule()
	rule.addId(it.@id)
	def premises
	def conclusions
	if (forward)
	{
		premises = it.if
		conclusions = it.then
	}
	else
	{
		premises = it.then
		conclusions = it.if
	}
	
	//checking premises
	premises.attr.each{
		if(valeRegla){
			String nombre = it.@name
			String valor = it.text()  
			
			if(!wk.isInWorkingMemory(nombre, valor)){
				valeRegla = false
			} else {
				rule.addPremise(nombre, valor)
			}
		}
	}
	
	if(valeRegla){
		print "   OK\n"
		conclusions.attr.each{           
			rule.addConclusion(it.@name, it.text())
		}
		if(!lista.contains(rule)){
			lista.add(rule)
		}
	}
	else
		print "   NO\n"
}

def workingMemory = new WorkingMemory()
def listRules = new ArrayList<Rule>()

workingMemory.memory = mapEntrada

def index = 0
def ciclos = 1
def temp = ""
mapEntrada.each { key, value ->
	temp += "${key}=${value},"
}

println "\n\n  WorkingMemory: ${workingMemory.memoryToString()}"

def isForward = false
if (((String)records.@forward).equals("true"))
	isForward = true

def showAll = false
if (obj.equals("all"))
	showAll = true


while (!temp.contains(obj)){
	try{
		println "\n\n------------------ Ciclo Nº${ciclos} -------------------------"
		records.rule.each{checkRule(it, listRules, workingMemory, isForward)}		
		
		workingMemory.addRule(listRules.get(index))
		//listRules.remove(index)
		index++;
		
	}catch(Exception e){
		if (showAll)
		{
			break;
		}
		println "\n\nNo se llego al objetivo  ==> Hay que pedirle al usuario que ingrese algo mas"
		input(CONDICIONES, workingMemory.memory)
	} finally{		
		ciclos++
		//temp = entrada + ","+workingMemory.getConclusions()
		temp = workingMemory.memoryToString()
		println "\n\n  WorkingMemory: ${temp}"
	}
}
if (!showAll)
	println "\n\nSe llego al objetivo ==> ${obj}"




